package models

import (
	"context"
	"encoding/json"
	"errors"
	"go-chain-api/global"
	"go-chain-api/tools"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type WatchAddressConfig struct {
	Id          string `bson:"_id,omitempty" json:"id"`
	ChainId     uint   `bson:"chainId" json:"chainId"`
	ChainName   string `bson:"chainName" json:"chainName"`
	Address     string `bson:"address" json:"address"`
	Token       string `bson:"token" json:"token"`
	CallBackUrl string `bson:"callBackUrl" json:"callBackUrl"`
	UserId      string `bson:"userId" json:"userId"`
	PrivateKey  string `bson:"privateKey" json:"privateKey"`
	Type        string `bson:"type" json:"type"`
	Timestamp   uint64 `bson:"timestamp" json:"timestamp"`
	IsDel       uint   `bson:"isDel" json:"isDel"`  //删除状态 0.未删除 1.已删除
	BusinessId  string `bson:"businessId" json:"-"` //业务id
}

// Insert 插入
func (wac WatchAddressConfig) Insert() error {
	client := global.DBEngine.Database(global.DbConfig.DbName).Collection("watch_address_config")
	_, err := client.InsertOne(context.TODO(), wac)
	if err != nil {
		return err
	}
	return nil
}

// DeleteById 删除
func (wac WatchAddressConfig) DeleteById(id string) error {
	client := global.DBEngine.Database(global.DbConfig.DbName).Collection("watch_address_config")
	objID, err := primitive.ObjectIDFromHex(id)
	if err != nil {
		return err
	}
	deleteResult, err := client.DeleteOne(context.TODO(), bson.M{"_id": objID})
	if err != nil {
		return err
	}
	if deleteResult.DeletedCount == 0 {
		return errors.New("检查ID是否正确")
	}
	return nil
}

// GetList 获取列表
func (wac WatchAddressConfig) GetList(userId string, pageIndex uint, pageSize uint) (int64, []WatchAddressConfig, error) {
	var watchAddressConfigs []WatchAddressConfig
	client := global.DBEngine.Database(global.DbConfig.DbName).Collection("watch_address_config")

	// 查找
	filter := bson.D{{"userId", userId}}
	clientOptions := options.Find()
	clientOptions.SetSort(bson.D{{"_id", -1}})
	clientOptions.SetSkip(int64(pageIndex))
	clientOptions.SetLimit(int64(pageSize))

	// 获取总数
	count, err := client.CountDocuments(context.TODO(), filter)
	if err != nil {
		return 0, []WatchAddressConfig{}, err
	}

	find, err := client.Find(context.TODO(), filter, clientOptions)
	if err != nil {
		return 0, []WatchAddressConfig{}, err
	}

	err = find.All(context.TODO(), &watchAddressConfigs)
	if err != nil {
		return 0, []WatchAddressConfig{}, err
	}

	return count, watchAddressConfigs, nil
}

// DeleteById 删除
func (wac WatchAddressConfig) DeleteByAddress() error {
	client := global.DBEngine.Database(global.DbConfig.DbName).Collection("watch_address_config")
	update := bson.M{"$set": bson.M{"isDel": 1}}
	result, err := client.UpdateOne(context.TODO(), bson.M{"address": wac.Address, "userId": wac.UserId}, update)

	if result.ModifiedCount == 0 {
		return errors.New("get data error")
	}
	return err
}

func GenerateAddress(userId string, mainCoinType int64, chainName string) (string, error) {
	var watchAddressConfig WatchAddressConfig
	var privateKeyHex string
	//switch chainName {
	//case "TRX":
	//	privateKey, _ := crypto.GenerateKey()
	//	privateKeyBytes := crypto.FromECDSA(privateKey)
	//	publicKey := privateKey.Public()
	//	publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey)
	//	addrStr := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
	//	addrStr = "41" + addrStr[2:]
	//	addb, _ := hex.DecodeString(addrStr)
	//	firstHash := sha256.Sum256(addb)
	//	secondHash := sha256.Sum256(firstHash[:])
	//	secret := secondHash[:4]
	//	addb = append(addb, secret...)
	//	address = base58.Encode(addb)
	//	privateKeyHex = hexutil.Encode(privateKeyBytes)[2:]
	//default:
	//	privateKeyRe, err := crypto.GenerateKey()
	//	if err != nil {
	//		return "", err
	//	}
	//	// 将私钥的D字段（其实是个大数）转换为字节切片
	//	privateKeyBytes := privateKeyRe.D.Bytes()
	//
	//	// 将字节切片转换为十六进制字符串
	//	privateKeyHex = hex.EncodeToString(privateKeyBytes)
	//	address = crypto.PubkeyToAddress(privateKeyRe.PublicKey).Hex()
	//}

	var flag string
	if chainName == "TRX" {
		flag = "TRX"
	} else {
		flag = "EVM"
	}

	url := "http://192.168.0.188:8888/api/generateAddress?flag=" + flag
	body, err := tools.SendGet(url)
	if err != nil {

		return "", err
	}

	var data AddressData
	err = json.Unmarshal(body, &data)
	if err != nil {
		return "", err
	}
	if data.Code != 200 {
		return "", errors.New(data.Msg)
	}

	//这个域名到时候得换 这个到时候可以用127.0.0.1:8848
	callBack := global.CallBackUrlConfig.UpgradeUrl
	var userInfo User
	userClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("user")
	err = userClient.FindOne(context.TODO(), bson.M{"role": "1"}).Decode(&userInfo)
	if err != nil {
		return "", err
	}

	var chainConfig ChainConfig
	chainConfigClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("scan_config")
	err = chainConfigClient.FindOne(context.TODO(), bson.M{"chainName": chainName, "udunId": mainCoinType}).Decode(&chainConfig)
	if err != nil {
		return "", err
	}

	//这里是存入u盾的address表 所以userId用系统用户的id取创建地址
	watchAddressConfig.UserId = userInfo.Id
	watchAddressConfig.ChainId = chainConfig.ChainID
	watchAddressConfig.PrivateKey = privateKeyHex
	watchAddressConfig.ChainName = chainName
	watchAddressConfig.Type = "udun"
	watchAddressConfig.CallBackUrl = callBack
	watchAddressConfig.Address = data.Data.Address
	watchAddressConfig.BusinessId = data.Data.Id
	err = watchAddressConfig.Insert()
	if err != nil {
		return "", err
	}

	//这里是存入我们自己的address表
	var generateAddressConfig GenerateAddressConfig
	generateAddressConfig.UserId = userId
	generateAddressConfig.ChainId = chainConfig.ChainID
	generateAddressConfig.PrivateKey = privateKeyHex
	generateAddressConfig.Address = data.Data.Address
	generateAddressConfig.ChainName = chainName
	generateAddressConfig.Type = "udun"
	generateAddressConfig.CallBackUrl = callBack
	err = generateAddressConfig.Insert()
	if err != nil {
		return "", err
	}
	return data.Data.Address, nil
}
